package NG::Ext::Cron;
use strict;
use warnings;

use POSIX;

use base 'Schedule::Cron';

sub prepare_wait { 
	my $self = shift;

	# Install reaper now.
	$SIG{'CHLD'} = 'IGNORE';
}
sub before_wait {
	my $self = shift;

	$self->_cleanup_process_list;
	$self->_build_initial_queue;
	delete $self->{entries_changed};
	die "Nothing in schedule queue" unless @{$self->{queue}};

}
sub wait_next{
	my $self = shift;
	
	my ($index,$time) = @{shift @{$self->{queue}}};
	my $now = time;
	my $sleep = 0;

	unless ($time) {
		die "Internal: No time found, self: ",$self->{queue},"\n";
	}
	if ($time <= $now) {
		$sleep = 1;
	} else {
		$sleep = $time - $now;
	}
	
	sleep($sleep);
	if($time > time()+1){
		return;
	}
	$self->_execute($index);
}
sub _execute { 
	my $self = shift;
	my $index = shift;

	my $entry = $self->get_entry($index) || die "Internal: No entry with index $index found in ";
	
	my $pid;
	
	unless(defined($pid = fork)) {
		die "fork error '$!'";
	}elsif($pid) {
		return;
	}
	unless(POSIX::setsid()){
		die "Cannot POSIX::setsid(): '$!'\n";
	}
	
	# Child
	my $dispatch = $entry->{dispatcher};
	die "No subroutine provided with $dispatch" unless ref($dispatch) eq "CODE";
	my $args = $entry->{args};
	
	my @args = ();
	if (defined($args) && defined($args->[0])) {
		push @args,@$args;
	}
	
	my $dispatch_result;
	# Let dispatcher die if needed.
	$dispatch_result = &$dispatch(@args);
	
	exit;
}
	
	
1;
